#include "xHardBuffer.h"
#include "xLogManager.h"

namespace XE	
{


	xVertexHardBuffer::xVertexHardBuffer(UINT vertexCount,UINT PreSize)
		:xHardBuffer(vertexCount* PreSize,xHardBuffer_Vertex),m_vertexCount(vertexCount),m_VertexSize(PreSize)
	{

	}

	xVertexHardBuffer::~xVertexHardBuffer()
	{
		xHardBufferManager::getSingleton().NotifyRemoveVertexBuffer(this);
	}
/*/--------------------------------------------------------------------------------------------------------------------

IndexHardBuffer

//---------------------------------------------------------------------------------------------------------------------*/
	xIndexHardBuffer::xIndexHardBuffer(UINT indexCount,xIndexHardBufferType indextype)
		:xHardBuffer(indexCount*indextype,xHardBuffer_Index),m_IndexCount(indexCount),m_IndexType(indextype)
	{

	}

	xIndexHardBuffer::~xIndexHardBuffer()
	{
		xHardBufferManager::getSingleton().NotifyRemoveIndexBuffer(this);

	}


	/*/--------------------------------------------------------------------------------------------------------------------

	HardBufferManager

	//---------------------------------------------------------------------------------------------------------------------*/

	xHardBufferManager* Singleton<xHardBufferManager>::ms_Singleton = NULL;

	xVertexHardBufferPtr xHardBufferManager::CreateVertexHardBuffer(UINT vertexCount,UINT PreVertexSize)
	{
		xVertexHardBuffer* pVerBufer =   CreateVertexHardBufferImplement(vertexCount,PreVertexSize);
		if(pVerBufer==NULL)
		{
			xLogMessager::getSingleton().logMessage("Create VertexHardBuffer Fail");
			return xVertexHardBufferPtr();
		}
		m_VertexBufferVector.push_back(pVerBufer);
		return xVertexHardBufferPtr(pVerBufer);

	}

	xIndexHardBufferPtr xHardBufferManager::CreateIndexHardBuffer(UINT indexCount,xIndexHardBufferType indexType)
	{

		xIndexHardBuffer* pIndexBufer = CreateIndexHardBufferImplement(indexCount,indexType);
		if(pIndexBufer==NULL)
		{
			xLogMessager::getSingleton().logMessage("Create IndexHardBuffer Fail");
			return xIndexHardBufferPtr();
		}
		m_IndexBufferVector.push_back(pIndexBufer);
		return xIndexHardBufferPtr(pIndexBufer);
	}


	void xHardBufferManager::NotifyRemoveIndexBuffer(xIndexHardBuffer* pIndexBuf)
	{
		xIndexHardBufferVector::iterator it = std::find(m_IndexBufferVector.begin(),m_IndexBufferVector.end(),pIndexBuf);
		if(it!=m_IndexBufferVector.end())
		{
			m_IndexBufferVector.erase(it);

		}

	}

	void xHardBufferManager::NotifyRemoveVertexBuffer(xVertexHardBuffer* pVertexBuf)
	{

		xVertexBufferVector::iterator it = std::find(m_VertexBufferVector.begin(),m_VertexBufferVector.end(),pVertexBuf);
		if(it!=m_VertexBufferVector.end())
		{
			m_VertexBufferVector.erase(it);

		}
	}



	xVertexDeclaration*    xHardBufferManager::CreateVertexDeclaration()
	{
		xVertexDeclaration*pvd =  CreateVertexDeclarationImplement();
		if(pvd==NULL)
		{
			xLogMessager::getSingleton().logMessage("d3d Create vertexDeclaration Fail");
			throw("d3d Create vertexDeclaration Fail");
		}
		m_VertexDeclVector.push_back(pvd);
		return pvd;

	}



	bool xHardBufferManager::DestoryVertexDeclaration(xVertexDeclaration* pvd)
	{
		if(pvd==NULL)
			return false;
		xVertexDeclarationVector::iterator it = 	std::find( m_VertexDeclVector.begin(),m_VertexDeclVector.end(),pvd);
		if(it!=m_VertexDeclVector.end())
		{
			SafeDelete(*it);
			m_VertexDeclVector.erase(it);
			return true;
		}
		return false;	
	}


	void xHardBufferManager::DestoryAllVertexDeclaration()
	{
			xVertexDeclarationVector::iterator it = m_VertexDeclVector.begin();
			xVertexDeclarationVector::iterator endit=	m_VertexDeclVector.end();
			for(;it!=endit	;++it)
			{
				SafeDelete(*it);
			}
			m_VertexDeclVector.clear();

	}



	void xHardBufferManager::LostDevice()
	{
		//DestoryAllVertexDeclaration();

		ClearAllDynamicHardBuffer();
		return ;
	}


	xVertexHardBuffer*   xHardBufferManager::RequestDynamicVertexHardBuffer(WORD preSize,UINT VertexCount)
	{

		DynamicVertexHardBufferMap::iterator it = m_DynamicVertexHardBufferMap.find(preSize);
		if(it!=m_DynamicVertexHardBufferMap.end())
		{
			if(it->second->GetVertexCount()<VertexCount)
			{
				if(SUCCEEDED(it->second->Resize(VertexCount)))
				{
					return it->second;
				}else
				{
					SafeDelete(it->second);
					m_DynamicVertexHardBufferMap.erase(it);
					return NULL;
				}

			}else
			{
				return it->second;
			}

		}else
		{
			
			xVertexHardBuffer* pBuffer = CreateVertexHardBufferImplement( VertexCount,preSize,D3DUSAGE_DYNAMIC|D3DUSAGE_WRITEONLY);
		    if(pBuffer==NULL)
			{
				return NULL;
			}

			m_DynamicVertexHardBufferMap.insert(std::make_pair(preSize,pBuffer));
			return pBuffer;
		}

		return NULL;
	}


	void  xHardBufferManager::ClearAllDynamicHardBuffer()
	{

		DynamicVertexHardBufferMap::iterator it = m_DynamicVertexHardBufferMap.begin();
		DynamicVertexHardBufferMap::iterator itend = m_DynamicVertexHardBufferMap.end();
		for(;it!=itend;++it)
		{
			SafeDelete(it->second)
		}
		m_DynamicVertexHardBufferMap.clear();

		SafeDelete(m_DynamicIndexHardBuffer[0])
		SafeDelete(m_DynamicIndexHardBuffer[1])


	}

    xIndexHardBuffer* xHardBufferManager::RequestDynamicIndexHardBuffer(xIndexHardBufferType indextype,UINT IndexCount)
	{

		UINT bufIndex = 0;
		if(indextype ==IndexHardBufferType_32)
		{
	        bufIndex = 1;
		}

		if(m_DynamicIndexHardBuffer[bufIndex]==NULL)
		{
           xIndexHardBuffer* pBuf = CreateIndexHardBufferImplement(IndexCount,indextype,D3DUSAGE_DYNAMIC|D3DUSAGE_WRITEONLY);
		   if(pBuf==NULL)
		   {
			   xLogMessager::getSingleton().logMessage("Create Dynamic IndexBuffer Fail");
			   return NULL;
		   }
		   m_DynamicIndexHardBuffer[bufIndex] = pBuf;
		   return pBuf;
		}else
		{
			if( m_DynamicIndexHardBuffer[bufIndex]->GetIndexCount()<IndexCount)
			{
				if(FAILED(m_DynamicIndexHardBuffer[bufIndex]->Resize(IndexCount)))
				{
					SafeDelete (m_DynamicIndexHardBuffer[bufIndex])
					return NULL;
				}
			}
			return m_DynamicIndexHardBuffer[bufIndex];
		}
	}


}